package com.study.quiz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.study.quiz.dto.PageDTO;
import com.study.quiz.dto.QuestionDTO;
import com.study.quiz.mapper.QuestionMapper;
import com.study.quiz.mapper.UserMapper;
import com.study.quiz.pojo.Question;
import com.study.quiz.pojo.User;
import com.study.quiz.service.QuestionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author CJunGod
 * @create 2020-03-05 17:51
 **/
@Slf4j
@Service
@Transactional
public class QuestionServiceImpl implements QuestionService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private QuestionMapper questionMapper;

    public PageDTO findList(String search, Integer page, Integer size) {
        Integer count;
        if (StringUtils.isNotBlank(search)) {
            String[] splitTag = StringUtils.split(search, " ");
            search = Arrays.stream(splitTag).collect(Collectors.joining("|"));
            count = questionMapper.findBySearch(search);
        } else {
            count = questionMapper.selectCount(null);
        }

        Integer totalPage;
        PageDTO pageDTO = new PageDTO();
        if (count % size == 0) {
            totalPage = count / size;
        } else {
            totalPage = count / size + 1;
        }
        pageDTO.setTotalPage(totalPage);

        if (page < 1) {
            page = 1;
        }
        if (page > totalPage) {
            page = totalPage;
        }
        PageHelper.startPage(page, size);
        PageInfo<Question> pageInfo;
        if (StringUtils.isNotBlank(search)) {
            pageInfo = new PageInfo<>(questionMapper.findList(search));
        } else {
            pageInfo = new PageInfo<>(questionMapper.selectList(new QueryWrapper<Question>()
                    .orderByDesc("GMT_CREATE")));
        }
        List<QuestionDTO> dtoList = new ArrayList<>();
        pageInfo.getList().forEach(q -> {
            User user = userMapper.selectById(q.getCreator());
            QuestionDTO dto = new QuestionDTO(q, user);
            dtoList.add(dto);
        });

        pageDTO.setDtoList(dtoList);

        List<Integer> pageList = new ArrayList<>();
        pageList.add(page);

        for (int i = 1; i <= 3; i++) {
            if (page - i > 0) {
                pageList.add(0, page - i);
            }

            if (page + i <= pageInfo.getPages()) {
                pageList.add(page + i);
            }
        }

        pageDTO.setPages(pageList);
        pageDTO.setPage(page);

        if (pageInfo.getPageNum() == 1) {
            pageDTO.setShowPrevious(false);
        } else {
            pageDTO.setShowPrevious(true);
        }

        if (pageInfo.getPages() == page) {
            pageDTO.setShowNet(false);
        } else {
            pageDTO.setShowNet(true);
        }

        if (pageDTO.getPages().contains(1)) {
            pageDTO.setShowFirstPage(false);
        } else {
            pageDTO.setShowFirstPage(true);
        }

        if (pageDTO.getPages().contains(pageInfo.getPages())) {
            pageDTO.setShowEndPage(false);
        } else {
            pageDTO.setShowEndPage(true);
        }

        return pageDTO;
    }

    @Override
    public PageDTO findByUserId(Integer userId, Integer page, Integer size) {
        Integer count = questionMapper.selectCount(new QueryWrapper<Question>().eq("creator", userId));
        Integer totalPage;
        PageDTO pageDTO = new PageDTO();
        if (count % size == 0) {
            totalPage = count / size;
        } else {
            totalPage = count / size + 1;
        }
        pageDTO.setTotalPage(totalPage);

        if (page < 1) {
            page = 1;
        }
        if (page > totalPage && totalPage != 0) {
            page = totalPage;
        } else if (totalPage == 0) {
            page = 1;
        }

        PageHelper.startPage(page, size);
        Map<String, Object> map = new HashMap<>();
        map.put("creator", userId);
        PageInfo<Question> pageInfo = new PageInfo<>(questionMapper.selectByMap(map));
        List<QuestionDTO> dtoList = new ArrayList<>();
        pageInfo.getList().forEach(q -> {
            User user = userMapper.selectById(q.getCreator());
            QuestionDTO dto = new QuestionDTO(q, user);
            dtoList.add(dto);
        });

        pageDTO.setDtoList(dtoList);

        List<Integer> pageList = new ArrayList<>();
        pageList.add(page);

        for (int i = 1; i <= 3; i++) {
            if (page - i > 0) {
                pageList.add(0, page - i);
            }

            if (page + i <= pageInfo.getPages()) {
                pageList.add(page + i);
            }
        }

        pageDTO.setPages(pageList);
        pageDTO.setPage(page);

        if (pageInfo.getPageNum() == 1) {
            pageDTO.setShowPrevious(false);
        } else {
            pageDTO.setShowPrevious(true);
        }

        if (pageInfo.getPages() == page || totalPage == 0) {
            pageDTO.setShowNet(false);
        } else {
            pageDTO.setShowNet(true);
        }

        if (pageDTO.getPages().contains(1)) {
            pageDTO.setShowFirstPage(false);
        } else {
            pageDTO.setShowFirstPage(true);
        }

        if (pageDTO.getPages().contains(pageInfo.getPages()) || totalPage == 0) {
            pageDTO.setShowEndPage(false);
        } else {
            pageDTO.setShowEndPage(true);
        }

        return pageDTO;
    }

    @Override
    public QuestionDTO findById(Integer questionId) {
        Question question = questionMapper.selectById(questionId);
        User user = userMapper.selectById(question.getCreator());
        QuestionDTO questionDTO = new QuestionDTO();
        questionDTO.setQuestion(question);
        questionDTO.setUser(user);

        return questionDTO;
    }

    @Override
    public Integer insert(Question question) {

        return questionMapper.insert(question);
    }

    @Override
    public Question findByQuestionId(Integer questionId) {

        return questionMapper.selectById(questionId);
    }

    @Override
    public Integer updateById(Question question) {

        return questionMapper.updateById(question);
    }

    @Override
    public Integer updateView(Integer questionId, Long gmtModified) {

        return questionMapper.updateView(questionId, gmtModified);
    }

    @Override
    public Integer updateComment(Integer questionId, Long gmtModified) {

        return questionMapper.updateComment(questionId, gmtModified);
    }

    @Override
    public List<QuestionDTO> selectRelated(QuestionDTO questionDTO) {
        if (StringUtils.isBlank(questionDTO.getQuestion().getTag())) {
            return new ArrayList<>();
        }
        String[] splitTag = StringUtils.split(questionDTO.getQuestion().getTag(), ",");
        String regexpTag = Arrays.stream(splitTag).collect(Collectors.joining("|"));
        Question question = new Question();
        question.setTag(regexpTag);
        question.setId(questionDTO.getQuestion().getId());
        List<Question> questions = questionMapper.findByTag(question);
        List<QuestionDTO> collect = questions.stream().map(q -> {
            QuestionDTO questionDTO1 = new QuestionDTO();
            questionDTO1.setQuestion(q);
            return questionDTO1;
        }).collect(Collectors.toList());

        return collect;
    }

}
